﻿#include "ISEA4TQuery.hpp"

using namespace NNU::DGGS::Kernel::ISEA4T;

void ISEA4TQuery::init()
{
	for (int i = 0; i <MaxLevel; i++)
	{
		this->maxRow[i] = (long long int)(pow(2, i));
		this->fMaxCol[i] = (long long int)(pow(2, i+1));
		this->eMaxCol[i] = 3*this->maxRow[i];
		this->vMaxCol[i] = (long long int)(pow(2, i));
	}
}

 ISEA4TQuery::~ISEA4TQuery()
{
	delete[] this->maxRow;
    this->maxRow= nullptr;
	delete[] this->fMaxCol;
    this->fMaxCol= nullptr;
	delete[] this->eMaxCol;
    this->eMaxCol= nullptr;
	delete[] this->vMaxCol;
    this->vMaxCol= nullptr;
}

//获取相邻的二十面体大菱形块列表
int* getNbrDiamonds(int basePartition)
{
	if (basePartition == 0)
	{
		int* diamondList = new int[5];
		diamondList[0] = 3;
		diamondList[1] = 4;
		diamondList[2] = 5;
		diamondList[3] = 1;
		diamondList[4] = 2;
		return diamondList;
	}
	else if (basePartition == 11)
	{
		int* diamondList = new int[5];
		diamondList[0] = 10;
		diamondList[1] = 9;
		diamondList[2] = 8;
		diamondList[3] = 7;
		diamondList[4] = 6;
		return diamondList;
	}
	else if (basePartition < 6)
	{
		int* diamondList = new int[4];
		int case2adjTbl[][4] = {
		   {5, 2, 6, 10},  // q == 1
		   {1, 3, 7, 6},   // q == 2
		   {2, 4, 8, 7},   // q == 3
		   {3, 5, 9, 8},   // q == 4
		   {4, 1, 10, 9} }; // q == 5
		diamondList[0] = case2adjTbl[basePartition - 1][0];
		diamondList[1] = case2adjTbl[basePartition - 1][1];
		diamondList[2] = case2adjTbl[basePartition - 1][2];
		diamondList[3] = case2adjTbl[basePartition - 1][3];
		return diamondList;
	}
	else if (basePartition <= 10)
	{
		int* diamondList = new int[4];
		int case2adjTbl[][4] = {
		   {1, 2, 7, 10},  // q == 6
		   {2, 3, 8, 6},   // q == 7
		   {3, 4, 9, 7},   // q == 8
		   {4, 5, 10, 8},  // q == 9
		   {5, 1, 6, 9} };  // q == 10
		diamondList[0] = case2adjTbl[basePartition - 6][0];
		diamondList[1] = case2adjTbl[basePartition - 6][1];
		diamondList[2] = case2adjTbl[basePartition - 6][2];
		diamondList[3] = case2adjTbl[basePartition - 6][3];
		return diamondList;
	}
	else
	{
		return nullptr;
	}
}

bool isUp(long long col)
{
	if (col % 2 == 0)
	{
		return false;
	}
	else
	{
		return true;
	}
}

//面找面
void ISEA4TQuery::fromCellGetRelativeCells(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{

	int basePartition = code.basePartition;
	long long int row = code.row;
	long long int col = code.col;
	int* diamondList = getNbrDiamonds(code.basePartition);
    if(code.levelZ == -1)
    {
        elementNum=3;
        results = new DGGSElementCode[elementNum];
    }
    else
    {
        elementNum=3*3;
        results = new DGGSElementCode[elementNum];
        //sideFace
        DGGSElementCode *edges= nullptr;
        int edgesNum;
        this->fromCellGetBoundary(code,edges,edgesNum);
        for(int i=0;i<edgesNum;i++)
        {
            results[edgesNum+i]=edges[i];
            results[edgesNum+i].elementType=DGGSElementType::SideFace;
            results[edgesNum*2+i]=results[edgesNum+i];
            results[edgesNum*2+i].levelZ= edges[i].levelZ + 1;
        }
        delete[]edges;
    }

	for (int i = 0; i < 3; i++)
	{
		results[i].level = code.level;
		results[i].elementType = DGGSElementType::Cell;
        results[i].levelZ=code.levelZ;
	}
	if (basePartition == 0 || basePartition == 11)
	{
		return;
	}
	else
	{
		if (isUp(col))
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = col + 1;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = col - 1;
			results[2].basePartition = basePartition;
			results[2].row = row - 1;
			results[2].col = col - 1;
		}
		else
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = col + 1;
			results[1].basePartition = basePartition;
			results[1].row = row + 1;
			results[1].col = col + 1;
			results[2].basePartition = basePartition;
			results[2].row = row;
			results[2].col = col - 1;
		}
		if (col == 0)
		{
			if (basePartition < 6)
			{
				results[2].basePartition = diamondList[3];
				results[2].row = row;
				results[2].col = this->fMaxCol[code.level] - 1;
			}
			else
			{
				results[2].basePartition = diamondList[3];
				results[2].row = this->maxRow[code.level]-1;
				results[2].col = this->fMaxCol[code.level] - 2-2*row;
			}
		}
		if (row == 0&& isUp(col))
		{
			if (basePartition < 6)
			{
				results[2].basePartition = diamondList[0];
				results[2].row = this->maxRow[code.level] - (col + 1) / 2;
				results[2].col = this->fMaxCol[code.level] - 1;
			}
			else
			{
				results[2].basePartition = diamondList[0];
				results[2].row = this->maxRow[code.level] - 1;
				results[2].col = col-1;
			}
		}
		if (col == this->fMaxCol[code.level] - 1)
		{
			if (basePartition < 6)
			{
				results[0].basePartition = diamondList[1];
				results[0].row = 0;
				results[0].col = this->fMaxCol[code.level] - (row * 2 + 1);
			}
			else
			{
				results[0].basePartition = diamondList[1];
				results[0].row = row;
				results[0].col = 0;
			}
		}
		if (row == this->maxRow[code.level] - 1 && !isUp(col))
		{
			if (basePartition < 6)
			{
				results[1].basePartition = diamondList[2];
				results[1].row = 0;
				results[1].col = col + 1;
			}
			else
			{
				results[1].basePartition = diamondList[2];
				results[1].row = this->maxRow[code.level] - 1-col/2;
				results[1].col = 0;
			}
		}
	}

    delete[]diamondList;
}
//父节点
void ISEA4TQuery::getVoxelParent(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    DGGSElementCode cell=code;
    cell.elementType=DGGSElementType::Cell;
    this->getCellParent(cell,results,elementNum);
    for(int i=0;i<elementNum;i++)
    {
        results[i].elementType=DGGSElementType::Voxel;
    }
}

void ISEA4TQuery::getCellParent(DGGSElementCode code, DGGSElementCode*& result,int& elementNum)
{
    elementNum=1;
    result=new DGGSElementCode[1];
    result->basePartition=code.basePartition;
	result->row = int(code.row/2);
	result->level =code.level- 1;
    result->levelZ=code.levelZ;
	if (code.row % 2 == 0)
	{
		if (code.col % 4 == 0)
		{
			result->col = code.col / 2;
		}
		else
		{
			result->col = 1 + 2 * (long long int)(code.col / 4);
		}
	}
	else
	{
		if ((code.col+1) % 4 == 0)
		{
			result->col = (code.col + 1) / 2 - 1;
		}
		else
		{
			result->col = (long long int)(code.col / 4) * 2;
		}
	}
}

void ISEA4TQuery::getEdgeParent(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    //一般情况
    int* diamondList = getNbrDiamonds(code.basePartition);

    elementNum=1;
    results=new DGGSElementCode[elementNum];
    results[0]=code;
    results[0].level-=1;

    //一般情况
    if(code.row%2==0)
    {
        switch (code.col % 6) {
            case 0:
                results[0].row=code.row/2;
                results[0].col=code.col/6*3;
                break;
            case 1:
                results[0].row=code.row/2;
                results[0].col=code.col/6*3+1;
                break;
            case 2:
            case 3:
            case 5:
                results[0].row=code.row/2;
                results[0].col=code.col/6*3+2;
                break;
            case 4:
                results[0].row=code.row/2;
                results[0].col=code.col/6*3+3;
                break;
            default:
                break;
        }
    }
    else
    {
        switch (code.col % 6) {
            case 0:
            case 1:
                results[0].row=code.row/2;
                results[0].col=code.col/6*3;
                break;
            case 3:
                results[0].row=code.row/2+1;
                results[0].col=code.col/6*3+2;
                break;
            case 2:
            case 4:
            case 5:
                results[0].row=code.row/2;
                results[0].col=code.col/6*3+1;
                break;
            default:
                break;
        }
    }
    //边界
    if(code.row%2==0&&code.col==this->eMaxCol[code.level]-2)
    {
        results[0].basePartition=diamondList[1];
        if(code.basePartition<6)
        {
            results[0].col=(this->maxRow[results->level]-1-results[0].row)*3+2;
            results[0].row=0;
        }
        else
        {
            results[0].col=0;
        }
    }
    if(results[0].row>this->maxRow[results[0].level]-1)
    {
        results[0].basePartition=diamondList[2];
        if(code.basePartition<6)
        {
            results[0].row=0;
        }
        else
        {
            results[0].row=this->maxRow[results[0].level]-1-results[0].col/3;
            results[0].col=0;
        }
    }
}

void ISEA4TQuery::getVertexParent(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    elementNum=0;
    if(code.row%2==0&&code.col%2==0)
    {
        elementNum=1;
        results=new DGGSElementCode[1];
        results[0]=code;
        results[0].level-=1;
        results[0].col/=2;
        results[0].row/=2;
    }
    else
    {
        int levelD=code.levelZ;
        code.levelZ=-1;
        results=new DGGSElementCode[2];
        int vertexesNum;
        DGGSElementCode*vertexes= nullptr;
        this->fromVertexGetRelativeVertexes(code,vertexes,vertexesNum);
        for(int i=0;i<vertexesNum;i++)
        {
            if(vertexes[i].row%2==0&&vertexes[i].col%2==0)
                results[elementNum++]=vertexes[i];
        }
        for(int i=0;i<elementNum;i++)
        {
            results[i].levelZ=levelD;
            results[i].level-=1;
            results[i].col/=2;
            results[i].row/=2;
        }
        delete []vertexes;
        vertexes= nullptr;

    }
}
//子节点
void ISEA4TQuery::getVoxelChildren(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    DGGSElementCode cell=code;
    cell.elementType=DGGSElementType::Cell;
    this->getCellChildren(cell,results,elementNum);
    for(int i=0;i<elementNum;i++)
    {
        results[i].elementType=DGGSElementType::Voxel;
    }
}

void ISEA4TQuery::getCellChildren(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    elementNum=4;

	results = new DGGSElementCode[4];
	for (int i = 0; i < 4; i++)
	{
		results[i].basePartition = code.basePartition;
		results[i].elementType = DGGSElementType::Cell;
		results[i].level = code.level + 1;
        results[i].levelZ=code.levelZ;
	}
	if (isUp(code.col))
	{
		results[0].row = code.row * 2;
		results[1].row = code.row * 2;
		results[2].row = code.row * 2;
		results[3].row = code.row * 2 + 1;
		results[0].col = 1 + (code.col - 1) * 2;
		results[1].col = 2 + (code.col - 1) * 2;
		results[2].col = 3 + (code.col - 1) * 2;
		results[3].col = 3 + (code.col - 1) * 2;
	}
	else
	{
		results[0].row = code.row * 2;
		results[1].row = code.row * 2 + 1;
		results[2].row = code.row * 2 + 1;
		results[3].row = code.row * 2 + 1;
		results[0].col = code.col* 2;
		results[1].col = code.col * 2;
		results[2].col = code.col * 2 + 1;
		results[3].col = code.col * 2 + 2;
	}
	elementNum = 4;
}

void ISEA4TQuery::getEdgeChildren(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    int* diamondList = getNbrDiamonds(code.basePartition);
    elementNum=4;
    results=new DGGSElementCode[elementNum];
    for(int i=0;i<elementNum;i++)
    {
        results[i].basePartition=code.basePartition;
        results[i].level=code.level+1;
        results[i].elementType=code.elementType;
        results[i].levelZ=code.levelZ;
    }
    if(code.col%3==2)
    {
        results[0].row=code.row*2-1;
        results[0].col=code.col/3*6+3;
        results[1].row=code.row*2;
        results[1].col=code.col/3*6+5;
        results[2].row=code.row*2;
        results[2].col=code.col/3*6+3;
        results[3].row=code.row*2;
        results[3].col=code.col/3*6+2;
        if(code.row==0)
        {
            results[0].basePartition=diamondList[0];
            if(code.basePartition<6)
            {
                results[0].row=this->maxRow[results[0].level]-1-results[0].col/3;
                results[0].col=this->eMaxCol[results[0].level]-2;
            }
            else
            {
                results[0].row=this->maxRow[results[0].level]-1;
            }
        }
    }
    else if(code.col%3==1)
    {
        results[0].row=code.row*2;
        results[0].col=code.col/3*6+1;

        results[1].row=code.row*2+1;
        results[1].col=code.col/3*6+5;

        results[2].row=code.row*2+1;
        results[2].col=code.col/3*6+4;

        results[3].row=code.row*2+1;
        results[3].col=code.col/3*6+2;
    }
    else
    {
        results[0].row=code.row*2;
        results[0].col=code.col/3*6;

        results[1].row=code.row*2+1;
        results[1].col=code.col/3*6+1;

        results[2].row=code.row*2+1;
        results[2].col=code.col/3*6;

        results[3].row=code.row*2;
        results[3].col=code.col/3*6-2;
        if(code.col==0)
        {
            results[3].basePartition=diamondList[3];
            if(code.basePartition<6)
            {
                results[3].col=this->eMaxCol[results[3].level]-2;
            }
            else
            {
                results[3].col=(this->maxRow[results[3].level]-1-results[3].row)*3;
                results[3].row=this->maxRow[results[3].level]-1;
            }
        }
    }

    delete[]diamondList;
    diamondList= nullptr;

}

void ISEA4TQuery::getVertexChildren(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    DGGSElementCode interiorChild=code;
    interiorChild.level+=1;
    interiorChild.row*=2;
    interiorChild.col*=2;
    interiorChild.levelZ=-1;

    int levelD=code.levelZ;
    code.levelZ=-1;
    int vertexesNum;
    DGGSElementCode*vertexes= nullptr;
    this->fromVertexGetRelativeVertexes(interiorChild,vertexes,vertexesNum);
    elementNum=vertexesNum+1;
    results=new DGGSElementCode[elementNum];

    results[0]=interiorChild;
    for(int i=0;i<vertexesNum;i++)
        results[i+1]=vertexes[i];
    for(int i=0;i<elementNum;i++)
        results[i].levelZ=levelD;

    delete[]vertexes;
    vertexes= nullptr;
}
//兄弟节点
void ISEA4TQuery::getVoxelSiblings(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    DGGSElementCode cell=code;
    cell.elementType=DGGSElementType::Cell;
    this->getCellSiblings(cell,results,elementNum);
    for(int i=0;i<elementNum;i++)
    {
        results[i].elementType=DGGSElementType::Voxel;
    }
}

void ISEA4TQuery::getCellSiblings(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    elementNum=0;
    results = new DGGSElementCode[3];
	DGGSElementCode *parent;
    int parentsNum=0;
	this->getCellParent(code, parent,parentsNum);

    DGGSElementCode* children;
    int childrenNum = 0;
	this->getCellChildren(parent[0], children, childrenNum);
	for (int j = 0; j < childrenNum; j++)
	{
		if (children[j].row == code.row && children[j].col == code.col)
			continue;
        results[elementNum++]= children[j];
	}
    delete[]parent;
    delete[]children;
    parent= nullptr;
    children= nullptr;
}

void ISEA4TQuery::getEdgeSiblings(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    int parentNum;
    DGGSElementCode*parent= nullptr;
    this->getEdgeParent(code,parent,parentNum);

    int firEdgesNum=0;
    DGGSElementCode*firEdges= nullptr;
    this->getEdgeChildren(parent[0],firEdges,firEdgesNum);

    int secEdgesNum=0;
    DGGSElementCode*secEdges= nullptr;
    if(parentNum==2)
        this->getEdgeChildren(parent[1],secEdges,secEdgesNum);

    elementNum=0;
    results=new DGGSElementCode[firEdgesNum+secEdgesNum];
    for(int i=0;i<firEdgesNum;i++)
    {
        if(code.row==firEdges[i].row&&code.col==firEdges[i].col&&code.basePartition==firEdges[i].basePartition)
            continue;
        results[elementNum++]=firEdges[i];
    }
    for(int i=0;i<secEdgesNum;i++)
    {
        if(code.row==secEdges[i].row&&code.col==secEdges[i].col&&code.basePartition==secEdges[i].basePartition)
            continue;
        results[elementNum++]=secEdges[i];
    }

    delete[]parent;
    parent= nullptr;
    delete[]firEdges;
    firEdges= nullptr;
    if(secEdges)
    {
        delete[]secEdges;
        secEdges= nullptr;
    }
}

void ISEA4TQuery::getVertexSiblings(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    int parentNum;
    DGGSElementCode*parent= nullptr;
    this->getVertexParent(code,parent,parentNum);

    int firVertexNum=0;
    DGGSElementCode*firVertexes= nullptr;
    this->getVertexChildren(parent[0], firVertexes, firVertexNum);

    int secVertexesNum=0;
    DGGSElementCode*secVertexes= nullptr;
    if(parentNum==2)
    {
        this->getVertexChildren(parent[1], secVertexes, secVertexesNum);
        results=new DGGSElementCode[firVertexNum+secVertexesNum-2];
    }
    else
        results=new DGGSElementCode[firVertexNum-1];

    elementNum=0;
    for(int i=0; i < firVertexNum; i++)
    {
        if(code.row == firVertexes[i].row && code.col == firVertexes[i].col && code.basePartition == firVertexes[i].basePartition
                &&code.elementType==firVertexes[i].elementType)
            continue;
        results[elementNum++]=firVertexes[i];
    }
    for(int i=0; i < secVertexesNum; i++)
    {
        if(code.row == secVertexes[i].row && code.col == secVertexes[i].col && code.basePartition == secVertexes[i].basePartition
               &&code.elementType==secVertexes[i].elementType)
            continue;
        results[elementNum++]=secVertexes[i];
    }

    delete[]parent;
    parent= nullptr;
    delete[]firVertexes;
    firVertexes= nullptr;
    if(secVertexes)
    {
        delete[]secVertexes;
        secVertexes= nullptr;
    }
}

//点找面
void ISEA4TQuery::fromVertexSearchRelativeCells(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
    long long int row=code.row;
    long long int col=code.col;
    int basePartition=code.basePartition;
    int* diamondList = getNbrDiamonds(code.basePartition);
    int levelD=code.levelZ;
    code.levelZ=-1;

    int edgesNum=0;
    DGGSElementCode *edges= nullptr;
    this->fromVertexGetAssociationBoundary(code, edges, edgesNum);

    if(levelD==-1)//维度
    {
        elementNum=edgesNum;
        results = new DGGSElementCode[elementNum];
    }
    else
    {
        elementNum=edgesNum*3;
        results = new DGGSElementCode[elementNum];
        for (int i = 0; i < edgesNum; i++)
        {
            results[i+edgesNum*2]=edges[i];
            results[i+edgesNum*2].elementType =DGGSElementType::SideFace;
            results[i+edgesNum*2].levelZ=levelD;

            results[i+edgesNum]=results[i+edgesNum*2];
            results[i+edgesNum].levelZ= levelD + 1;
        }
        delete[]edges;
    }


    if(row==0&&col==0)
    {
        for(int i=0;i<5;i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Cell;
            results[i].levelZ=levelD;
        }
        if(basePartition==0)
        {
            for(int i=0;i<6;i++)
            {
                results[i].basePartition= diamondList[i];
                results[i].row=0;
                results[i].col=this->fMaxCol[code.level]-1;
            }
        }
        else if(basePartition==11)
        {
            for(int i=0;i<5;i++)
            {
                results[i].basePartition= diamondList[i];
                results[i].row=this->maxRow[code.level]-1;
                results[i].col=0;
            }
        }
        else
        {
            if(basePartition<6)
            {
                results[0].basePartition= diamondList[0];
                results[0].row=this->maxRow[code.level]-1;
                results[0].col=this->fMaxCol[code.level]-2;

                results[1].basePartition= diamondList[0];
                results[1].row=this->maxRow[code.level]-1;
                results[1].col=this->fMaxCol[code.level]-1;

                results[2].basePartition= basePartition;
                results[2].row=0;
                results[2].col=0;

                results[3].basePartition= basePartition;
                results[3].row=0;
                results[3].col=1;

                results[4].basePartition= diamondList[3];
                results[4].row=0;
                results[4].col=this->fMaxCol[code.level]-1;
            }
            else
            {
                results[0].basePartition= diamondList[3];
                results[0].row=this->maxRow[code.level]-1;
                results[0].col=this->fMaxCol[code.level]-1;

                results[1].basePartition= diamondList[0];
                results[1].row=this->maxRow[code.level]-1;
                results[1].col=0;

                results[2].basePartition= basePartition;
                results[2].row=0;
                results[2].col=0;

                results[3].basePartition= basePartition;
                results[3].row=0;
                results[3].col=1;

                results[4].basePartition= diamondList[3];
                results[4].row=this->maxRow[code.level]-1;
                results[4].col=this->fMaxCol[code.level]-2;
            }
        }
    }
    else
    {
        for(int i=0;i<6;i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Cell;
            results[i].levelZ=levelD;
        }

        if(row==0)
        {
            if(basePartition<6)
            {
                results[0].basePartition= diamondList[0];
                results[0].row=this->maxRow[code.level]-1-col;
                results[0].col=this->fMaxCol[code.level]-1-1;

                results[1].basePartition= diamondList[0];
                results[1].row=this->maxRow[code.level]-1-col;
                results[1].col=this->fMaxCol[code.level]-1;

                results[2].basePartition= basePartition;
                results[2].row=0;
                results[2].col=2*col+1;

                results[3].basePartition= basePartition;
                results[3].row=0;
                results[3].col=2*col;

                results[4].basePartition= basePartition;
                results[4].row=0;
                results[4].col=2*col-1;

                results[5].basePartition= diamondList[0];
                results[5].row=this->maxRow[code.level]-col;
                results[5].col=this->fMaxCol[code.level]-1;
            }
            else
            {
                results[0].basePartition= diamondList[0];
                results[0].row=this->maxRow[code.level]-1;
                results[0].col=2*col-1;

                results[1].basePartition= diamondList[0];
                results[1].row=this->maxRow[code.level]-1;
                results[1].col=2*col;

                results[2].basePartition= basePartition;
                results[2].row=0;
                results[2].col=2*col+1;

                results[3].basePartition= basePartition;
                results[3].row=0;
                results[3].col=2*col;

                results[4].basePartition= basePartition;
                results[4].row=0;
                results[4].col=2*col-1;

                results[5].basePartition= diamondList[0];
                results[5].row=this->maxRow[code.level]-1;
                results[5].col=2*col-2;
            }
        }
        else if(col==0)
        {
            if(basePartition<6)
            {
                results[1].basePartition= basePartition;
                results[1].row=row-1;
                results[1].col=0;

                results[2].basePartition= basePartition;
                results[2].row=row;
                results[2].col=1;

                results[3].basePartition= basePartition;
                results[3].row=row;
                results[3].col=0;

                results[4].basePartition= diamondList[3];
                results[4].row=row;
                results[4].col=this->fMaxCol[code.level]-1;

                results[5].basePartition= diamondList[3];
                results[5].row=row-1;
                results[5].col=this->fMaxCol[code.level]-2;

                results[0].basePartition= diamondList[3];
                results[0].row=row-1;
                results[0].col=this->fMaxCol[code.level]-1;
            }
            else
            {
                results[1].basePartition= basePartition;
                results[1].row=row-1;
                results[1].col=0;

                results[2].basePartition= basePartition;
                results[2].row=row;
                results[2].col=1;

                results[3].basePartition= basePartition;
                results[3].row=row;
                results[3].col=0;

                results[4].basePartition= diamondList[3];
                results[4].row=this->maxRow[code.level]-1;
                results[4].col=(this->maxRow[code.level]-row)*2;

                results[5].basePartition= diamondList[3];
                results[5].row=this->maxRow[code.level]-1;
                results[5].col=(this->maxRow[code.level]-row)*2-1;

                results[0].basePartition= diamondList[3];
                results[0].row=this->maxRow[code.level]-1;
                results[0].col=(this->maxRow[code.level]-row)*2-2;
            }
        }
        else
        {
            results[1].basePartition= basePartition;
            results[1].row=row-1;
            results[1].col=2*col;

            results[2].basePartition= basePartition;
            results[2].row=row;
            results[2].col=2*col+1;

            results[3].basePartition= basePartition;
            results[3].row=row;
            results[3].col=2*col;

            results[4].basePartition= basePartition;
            results[4].row=row;
            results[4].col=2*col-1;

            results[5].basePartition= basePartition;
            results[5].row=row-1;
            results[5].col=2*col-2;

            results[0].basePartition= basePartition;
            results[0].row=row-1;
            results[0].col=2*col-1;
        }
    }

    delete[]edges;
    delete[]diamondList;

}
//点找边
void ISEA4TQuery::fromVertexGetAssociationBoundary(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{

    long long int row=code.row;
    long long int col=code.col;
    int basePartition=code.basePartition;
    int* diamondList = getNbrDiamonds(code.basePartition);
    if(code.levelZ == -1)
        elementNum=0;
    else
        elementNum=2;

    if(row==0&&col==0)
    {
        elementNum+=5;
        results=new DGGSElementCode[elementNum];
        for(int i=0;i<5;i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Edge;
            results[i].levelZ=code.levelZ;
        }
        if(basePartition==0)
        {
            for(int i=0;i<5;i++)
            {
                results[i].basePartition= diamondList[i];
                results[i].row=0;
                results[i].col=this->eMaxCol[code.level]-1;
            }
        }
        else if(basePartition==11)
        {
            for(int i=0;i<5;i++)
            {
                results[i].basePartition= i+6;
                results[i].row=this->maxRow[code.level]-1;
                results[i].col=0;
            }
        }
        else
        {
            if(basePartition<6)
            {
                results[0].basePartition= diamondList[0];
                results[0].row=this->maxRow[code.level]-1;
                results[0].col=this->eMaxCol[code.level]-2;

                results[1].basePartition= basePartition;
                results[1].row=0;
                results[1].col=0;

                results[2].basePartition= basePartition;
                results[2].row=0;
                results[2].col=1;

                results[3].basePartition= basePartition;
                results[3].row=0;
                results[3].col=2;

                results[4].basePartition= diamondList[3];
                results[4].row=0;
                results[4].col=this->eMaxCol[code.level]-1;
            }
            else
            {
                results[0].basePartition= diamondList[0];
                results[0].row=this->maxRow[code.level]-1;
                results[0].col=0;

                results[1].basePartition= basePartition;
                results[1].row=0;
                results[1].col=0;

                results[2].basePartition= basePartition;
                results[2].row=0;
                results[2].col=1;

                results[3].basePartition= basePartition;
                results[3].row=0;
                results[3].col=2;

                results[4].basePartition= diamondList[3];
                results[4].row=this->maxRow[code.level]-1;
                results[4].col=this->eMaxCol[code.level]-2;
            }
        }
    }
    else
    {
        elementNum+=6;
        results=new DGGSElementCode[elementNum];
        for(int i=0;i<6;i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Edge;
            results[i].levelZ=code.levelZ;
        }
        if(row==0)
        {
            if(basePartition<6)
            {
                results[0].basePartition= diamondList[0];
                results[0].row=this->maxRow[code.level]-1-col;
                results[0].col=this->eMaxCol[code.level]-1-1;

                results[1].basePartition= basePartition;
                results[1].row=0;
                results[1].col=3*col+2;

                results[2].basePartition= basePartition;
                results[2].row=0;
                results[2].col=3*col+1;

                results[3].basePartition= basePartition;
                results[3].row=0;
                results[3].col=3*col;

                results[4].basePartition= basePartition;
                results[4].row=0;
                results[4].col=3*col-1;

                results[5].basePartition= diamondList[0];
                results[5].row=this->maxRow[code.level]-col;
                results[5].col=this->eMaxCol[code.level]-1;
            }
            else
            {
                results[0].basePartition= diamondList[0];
                results[0].row=this->maxRow[code.level]-1;
                results[0].col=3*col;

                results[1].basePartition= basePartition;
                results[1].row=0;
                results[1].col=3*col+2;

                results[2].basePartition= basePartition;
                results[2].row=0;
                results[2].col=3*col+1;

                results[3].basePartition= basePartition;
                results[3].row=0;
                results[3].col=3*col;

                results[4].basePartition= basePartition;
                results[4].row=0;
                results[4].col=3*col-1;

                results[5].basePartition= diamondList[0];
                results[5].row=this->maxRow[code.level]-1;
                results[5].col=3*col-2;
            }
        }
        else if(col==0)
        {
            if(basePartition<6)
            {
                results[1].basePartition= basePartition;
                results[1].row=row-1;
                results[1].col=0;

                results[2].basePartition= basePartition;
                results[2].row=row;
                results[2].col=2;

                results[3].basePartition= basePartition;
                results[3].row=row;
                results[3].col=1;

                results[4].basePartition= basePartition;
                results[4].row=row;
                results[4].col=0;

                results[5].basePartition= diamondList[3];
                results[5].row=row;
                results[5].col=this->eMaxCol[code.level]-1;

                results[0].basePartition= diamondList[3];
                results[0].row=row-1;
                results[0].col=this->eMaxCol[code.level]-1-1;
            }
            else
            {
                results[1].basePartition= basePartition;
                results[1].row=row-1;
                results[1].col=0;

                results[2].basePartition= basePartition;
                results[2].row=row;
                results[2].col=2;

                results[3].basePartition= basePartition;
                results[3].row=row;
                results[3].col=1;

                results[4].basePartition= basePartition;
                results[4].row=row;
                results[4].col=0;

                results[5].basePartition= diamondList[3];
                results[5].row=this->maxRow[code.level]-1;
                results[5].col=(this->maxRow[code.level]-row)*3;

                results[0].basePartition= diamondList[3];
                results[0].row=this->maxRow[code.level]-1;
                results[0].col=(this->maxRow[code.level]-row)*3-2;
            }
        }
        else
        {
            results[1].basePartition= basePartition;
            results[1].row=row-1;
            results[1].col=col*3;

            results[2].basePartition= basePartition;
            results[2].row=row;
            results[2].col=col*3+2;

            results[3].basePartition= basePartition;
            results[3].row=row;
            results[3].col=col*3+1;

            results[4].basePartition= basePartition;
            results[4].row=row;
            results[4].col=col*3;

            results[5].basePartition= basePartition;
            results[5].row=row;
            results[5].col=col*3-1;

            results[0].basePartition= basePartition;
            results[0].row=row-1;
            results[0].col=col*3-2;
        }
    }

    if(code.levelZ != -1)
    {
        results[elementNum-2]=code;
        results[elementNum-2].elementType=DGGSElementType::SideEdge;
        results[elementNum-1]=results[elementNum-2];
        results[elementNum-1].levelZ+=1;
    }
    delete[]diamondList;
}
//边找点
void ISEA4TQuery::fromEdgeGetBoundary(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
    elementNum=2;
    long long int row=code.row;
    long long int col=code.col;
    int* diamondList = getNbrDiamonds(code.basePartition);
    results=new DGGSElementCode[2];

    //棱边
    if(code.elementType==DGGSElementType::SideEdge)
    {
        results[0]=code;
        results[0].elementType=DGGSElementType::Vertex;
        results[1]=results[0];
        results[1].levelZ= code.levelZ - 1;
        delete[]diamondList;
        return;
    }

    for(int i=0;i<2;i++)
    {
        results[i].level = code.level;
        results[i].elementType = DGGSElementType::Vertex;
        results[i].basePartition=code.basePartition;
        results[i].levelZ=code.levelZ;
    }

    //北极点
    if(code.row==0&&code.col==this->eMaxCol[code.level]-1&&code.basePartition<6)
    {
        results[0].row=code.row;
        results[0].col=code.col/3;

        results[1].basePartition=0;
        results[1].row=0;
        results[1].col=0;
    }
    //南极点
    else if(code.row==this->maxRow[code.level]-1&&code.col==0&&code.basePartition>5)
    {
        results[0].row=code.row;
        results[0].col=code.col/3;

        results[1].basePartition=11;
        results[1].row=0;
        results[1].col=0;
    }
    else
    {
        //一般情况
        if(col%3==0)
        {
            results[0].row=code.row;
            results[0].col=code.col/3;

            results[1].row=code.row+1;
            results[1].col=code.col/3;
        }
        else if(col%3==1)
        {
            results[0].row=code.row;
            results[0].col=code.col/3;

            results[1].row=code.row+1;
            results[1].col=code.col/3+1;
        }
        else if(col%3==2)
        {
            results[0].row=code.row;
            results[0].col=code.col/3;

            results[1].row=code.row;
            results[1].col=code.col/3+1;
        }

        //右上边
        if(code.col==this->eMaxCol[code.level]-1)
        {
            if(code.basePartition<6)
            {
                results[0].row=code.row;
                results[0].col=code.col/3;

                results[1].basePartition=diamondList[1];
                results[1].row=0;
                results[1].col=this->maxRow[code.level]-row;
            }
            else
            {
                results[0].row=code.row;
                results[0].col=code.col/3;

                results[1].basePartition=diamondList[1];
                results[1].row=code.row;
                results[1].col=0;
            }
        }
        if(code.col==this->eMaxCol[code.level]-2)
        {
            if(code.basePartition<6)
            {
                results[1].basePartition=diamondList[1];
                results[1].row=0;
                results[1].col=this->maxRow[code.level]-1-row;
            }
            else
            {
                results[1].basePartition=diamondList[1];
                results[1].row=code.row+1;
                results[1].col=0;
            }
        }

        //右下边
        if(code.row==this->maxRow[code.level]-1)
        {
            if(code.col%3==0)
            {
                if(code.basePartition<6)
                {
                    results[1].basePartition=diamondList[2];
                    results[1].row=0;
                    results[1].col=code.col/3;
                }
                else
                {
                    results[1].basePartition=diamondList[2];
                    results[1].row=this->maxRow[code.level]-code.col/3;
                    results[1].col=0;
                }

            }
            else if(code.col%3==1)
            {
                if(code.basePartition<6)
                {
                    results[1].basePartition=diamondList[2];
                    results[1].row=0;
                    results[1].col=code.col/3+1;
                }
                else
                {
                    results[1].basePartition=diamondList[2];
                    results[1].row=(this->maxRow[code.level]-1-code.col/3);
                    results[1].col=0;
                }
            }
        }

        if(code.row==0&&code.col==this->eMaxCol[code.level]-1&&code.basePartition<6)//北极点
        {
            results[1].basePartition=0;
            results[1].row=0;
            results[1].col=0;
        }
        if(code.row==this->maxRow[code.level]-1&&code.col==0&&code.basePartition>6)//南极点
        {
            results[1].basePartition=11;
            results[1].row=0;
            results[1].col=0;
        }

        //右端点
        if(code.row==this->maxRow[code.level]-1&&code.col==this->eMaxCol[code.level]-2)
        {
            if(code.basePartition<6)
            {
                results[1].basePartition=diamondList[1];
                results[1].row=0;
                results[1].col=0;
            }
            else
            {
                results[1].basePartition=diamondList[2];
                results[1].row=0;
                results[1].col=0;
            }
        }
    }

    delete[]diamondList;
}

//边找面
void ISEA4TQuery::fromEdgeGetAssociationBoundary(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
    //棱边
    if(code.elementType==DGGSElementType::SideEdge)
    {
        DGGSElementCode vertex=code;
        vertex.elementType=DGGSElementType::Vertex;
        vertex.levelZ=-1;

        DGGSElementCode*edges;
        int edgeNum=0;
        this->fromVertexGetAssociationBoundary(vertex,edges,edgeNum);
        elementNum=edgeNum;
        results = new DGGSElementCode[elementNum];

        for(int i=0;i<edgeNum;i++)
        {
            results[i]=edges[i];
            results[i].elementType=DGGSElementType::SideFace;
            results[i].levelZ=code.levelZ;
        }
        delete[]edges;
        return;
    }

    long long int row=code.row;
    long long int col=code.col;
    int* diamondList = getNbrDiamonds(code.basePartition);
    if(code.levelZ == -1)
    {
        elementNum=2;
        results=new DGGSElementCode[elementNum];
    }
    else
    {
        elementNum=4;
        results = new DGGSElementCode[elementNum];
        results[elementNum-2]=code;
        results[elementNum-2].elementType=DGGSElementType::SideFace;
        results[elementNum-1]=results[elementNum-2];
        results[elementNum-1].levelZ= code.levelZ - 1;
    }
    //一般情况
    for(int i=0;i<2;i++)
    {
        results[i].level = code.level;
        results[i].elementType = DGGSElementType::Cell;
        results[i].basePartition=code.basePartition;
        results[i].levelZ=code.levelZ;
    }
    if(code.col%3==0)
    {
        results[0].row=code.row;
        results[0].col=code.col/3*2-1;

        results[1].row=code.row;
        results[1].col=code.col/3*2;
    }
    else if(code.col%3==1)
    {
        results[0].row=code.row;
        results[0].col=code.col/3*2;

        results[1].row=code.row;
        results[1].col=code.col/3*2+1;
    }
    else if(code.col%3==2)
    {
        results[0].row=code.row-1;
        results[0].col=code.col/3*2+1;

        results[1].row=code.row;
        results[1].col=code.col/3*2;
    }

    //左上边
    if(code.row==0&&code.col%3==2)
    {
        results[1].row=code.row;
        results[1].col=code.col/3*2+1;
        if(code.basePartition<6)
        {
            results[0].basePartition=diamondList[0];
            results[0].row=this->maxRow[code.level]-1-code.col/3;
            results[0].col=this->fMaxCol[code.level]-1;
        }
        else
        {
            results[0].basePartition=diamondList[0];
            results[0].row=this->maxRow[code.level]-1;
            results[0].col=code.col/3*2+1;

        }
    }
    //左下边
    if(code.col==0)
    {
        if(code.basePartition<6)
        {
            results[0].basePartition=diamondList[3];
            results[0].row=code.row;
            results[0].col=this->fMaxCol[code.level]-1;
        }
        else
        {
            results[0].basePartition=diamondList[3];
            results[0].row=this->fMaxCol[code.level]-1;
            results[0].col=(this->maxRow[code.level]-1-code.row)*2;
        }
    }

    delete[]diamondList;
}

//面找边
void ISEA4TQuery::fromCellGetBoundary(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
    //侧面
    if(code.elementType==DGGSElementType::SideFace)
    {
        elementNum=4;
        results=new DGGSElementCode[elementNum];
        results[0]=code;
        results[0].elementType=DGGSElementType::Edge;
        results[1]=results[0];
        results[1].levelZ= code.levelZ - 1;

        //找棱边
        int vertexNum=0;
        DGGSElementCode* vertex;
        this->fromEdgeGetBoundary(results[0],vertex,vertexNum);
        results[2]=vertex[0];
        results[2].elementType=DGGSElementType::SideEdge;
        results[2].levelZ=code.levelZ;
        results[3]=vertex[1];
        results[3].elementType=DGGSElementType::SideEdge;
        results[3].levelZ=code.levelZ;

        delete[]vertex;
        vertex= nullptr;
        return;
    }
    elementNum=3;
    long long int row=code.row;
    long long int col=code.col;
    int* diamondList = getNbrDiamonds(code.basePartition);
    results=new DGGSElementCode[3];
    for(int i=0;i<3;i++)
    {
        results[i].levelZ=code.levelZ;
        results[i].level = code.level;
        results[i].elementType = DGGSElementType::Edge;
        results[i].basePartition=code.basePartition;
    }
    //一般情况
    if(code.col%2==1)
    {
        results[0].row=code.row;
        results[0].col=code.col/2*3+1;

        results[1].row=code.row;
        results[1].col=code.col/2*3+2;

        results[2].row=code.row;
        results[2].col=code.col/2*3+3;
    }
    else
    {
        results[0].row=code.row;
        results[0].col=code.col/2*3;

        results[1].row=code.row;
        results[1].col=code.col/2*3+1;

        results[2].row=code.row+1;
        results[2].col=code.col/2*3+2;
    }
    //右上边
    if(code.col==this->fMaxCol[code.level]-1)
    {
        if(code.basePartition<6)
        {
            results[2].basePartition=diamondList[1];
            results[2].row=0;
            results[2].col=(this->maxRow[code.level]-1-code.row)*3+2;
        }
        else
        {
            results[2].basePartition=diamondList[1];
            results[2].row=code.row;
            results[2].col=0;
        }

    }
    //右下边
    if(code.row==this->maxRow[code.level]-1&&code.col%2==0)
    {
        if(code.basePartition<6)
        {
            results[2].basePartition=diamondList[2];
            results[2].row=0;
            results[2].col=code.col/2*3+2;

        }
        else
        {
            results[2].basePartition=diamondList[2];
            results[2].row=this->maxRow[code.level]-1-code.col/3;
            results[2].col=0;
        }
    }
    delete[]diamondList;
}

//面找点
void ISEA4TQuery::fromCellGetRelativeVertexes(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
    //面找边
    DGGSElementCode *edges=nullptr;
    int edgesNum=0;
    fromCellGetBoundary(code, edges, edgesNum);
    elementNum=edgesNum;
    results=new DGGSElementCode[edgesNum];

    int resultCount=0;
    for(int i=0;i<2;i++)
    {
        DGGSElementCode *vertexs= nullptr;
        int vertexesCount=0;
        fromEdgeGetBoundary(edges[i], vertexs, vertexesCount);
        for(int j=0;j<2;j++)
        {
            int k=0;
            for(;k<resultCount;k++)
                if(vertexs[j].col == results[k].col && vertexs[j].row == results[k].row && vertexs[j].basePartition == results[k].basePartition)
                    break;
            if(k==resultCount)
                results[resultCount++]=vertexs[j];
        }
        delete[]vertexs;
        vertexs= nullptr;
    }
    delete[]edges;
    edges= nullptr;
}

//点找点
void ISEA4TQuery::fromVertexGetRelativeVertexes(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
    DGGSElementCode* edges= nullptr;
    int edgesNum=0;
    this->fromVertexGetAssociationBoundary(code,edges,edgesNum);
    elementNum=edgesNum;
    results=new DGGSElementCode[elementNum];

    int resultsCount=0;
    for(int i=0;i<edgesNum;i++)
    {
        //边找点
        DGGSElementCode*vertexes= nullptr;
        int vertexsNum=2;
        fromEdgeGetBoundary(edges[i], vertexes, vertexsNum);

        for(int j=0;j<vertexsNum;j++)
        {
            if(code.row == vertexes[j].row && code.col == vertexes[j].col && code.basePartition == vertexes[j].basePartition
                            &&code.elementType==vertexes[j].elementType)
                continue;
            else
                results[resultsCount++]=vertexes[j];
        }
        delete []vertexes;
        vertexes= nullptr;
    }
    delete []edges;
    edges= nullptr;
}

//边找边
void ISEA4TQuery::fromEdgeGetRelativeEdges(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
    //边找点
    DGGSElementCode* vertexs;
    int vertexsNum;
    this->fromEdgeGetBoundary(code,vertexs,vertexsNum);

    DGGSElementCode* FirEdges= nullptr;
    DGGSElementCode* SecEdges= nullptr;
    int Fir_edgesNum,Sec_edgesNum;
    this->fromVertexGetAssociationBoundary(vertexs[0],FirEdges,Fir_edgesNum);
    this->fromVertexGetAssociationBoundary(vertexs[1],SecEdges,Sec_edgesNum);
    elementNum=Fir_edgesNum+Sec_edgesNum-2;
    results=new DGGSElementCode[elementNum];

    int resultsCount=0;
    for(int j=0;j<Fir_edgesNum;j++)
    {
        if(FirEdges[j].col==code.col&&FirEdges[j].row==code.row&&FirEdges[j].basePartition==code.basePartition
                            &&FirEdges[j].elementType==code.elementType)
            continue;
        results[resultsCount++]=FirEdges[j];
    }
    for(int j=0;j<Sec_edgesNum;j++)
    {
        if(SecEdges[j].col==code.col&&SecEdges[j].row==code.row&&SecEdges[j].basePartition==code.basePartition
                            &&SecEdges[j].elementType==code.elementType)
            continue;
        results[resultsCount++]=SecEdges[j];
    }

    delete FirEdges;
    FirEdges=nullptr;
    delete SecEdges;
    SecEdges= nullptr;
    delete vertexs;
    vertexs= nullptr;
}

//体找面
void ISEA4TQuery::fromVoxelGetRelativeCells(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    int edgesNum=0;
    DGGSElementCode*edges= nullptr;

    DGGSElementCode*cell;
    cell=new DGGSElementCode[1];
    cell[0]=code;
    cell[0].elementType=DGGSElementType::Cell;

    this->fromCellGetBoundary(cell[0],edges,edgesNum);
    elementNum=edgesNum+2;
    results=new DGGSElementCode[elementNum];

    results[0]=code;
    results[0].elementType=DGGSElementType::Cell;
    results[1]=results[0];
    results[1].levelZ= code.levelZ - 1;

    for(int i=0;i<edgesNum;i++)
    {
        results[i+2]=edges[i];
        results[i+2].elementType=DGGSElementType::SideFace;
    }
    delete[]edges;
}

//体找边
void ISEA4TQuery::fromVoxelGetRelativeEdges(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    elementNum=3*3;
    results=new DGGSElementCode[elementNum];

    //上下面
    int cellNum=0;
    DGGSElementCode* cells;
    cells=new DGGSElementCode[2];
    cells[0]=code;
    cells[0].elementType=DGGSElementType::Cell;
    cells[1]=cells[0];
    cells[1].levelZ= code.levelZ - 1;
    for(int i=0;i<2;i++)
    {
        int edgesNum=0;
        DGGSElementCode*edges= nullptr;
        this->fromCellGetBoundary(cells[i],edges,edgesNum);
        for(int j=0;j<edgesNum;j++)
            results[i*edgesNum+j]=edges[j];
        delete []edges;
        edges= nullptr;
    }

    //棱边
    int vertexNum=0;
    DGGSElementCode* vertex;
    this->fromCellGetRelativeVertexes(cells[0],vertex,vertexNum);
    for(int k=0;k<vertexNum;k++)
    {
        results[vertexNum*2+k]=vertex[k];
        results[vertexNum*2+k].elementType=DGGSElementType::SideEdge;
    }
    delete []vertex;
    vertex= nullptr;
    delete []cells;
    cells= nullptr;
}

//体找点
void ISEA4TQuery::fromVoxelGetRelativeVertexes(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    elementNum=3*2;
    results=new DGGSElementCode[elementNum];

    //上下面
    int cellNum=0;
    DGGSElementCode* cells= nullptr;
    cells=new DGGSElementCode[2];
    cells[0]=code;
    cells[0].elementType=DGGSElementType::Cell;
    cells[1]=cells[0];
    cells[1].levelZ= code.levelZ - 1;

    //面找点
    for(int i=0;i<2;i++)
    {
        int vertexNum=0;
        DGGSElementCode* vertexs= nullptr;
        this->fromCellGetRelativeVertexes(cells[i],vertexs,vertexNum);
        for(int j=0;j<vertexNum;j++)
        {
            results[i*vertexNum+j]=vertexs[j];
        }
        delete []vertexs;
        vertexs= nullptr;
    }
    delete[]cells;
}

//面找体
void ISEA4TQuery::fromCellGetRelativeVoxels(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    elementNum=2;
    results=new DGGSElementCode[2];
    if(code.elementType==DGGSElementType::Cell)
    {
        results[0]=code;
        results[0].elementType=DGGSElementType::Voxel;
        results[1]=results[0];
        results[1].levelZ= code.levelZ + 1;
    }
    else if(code.elementType==DGGSElementType::SideFace)
    {
        DGGSElementCode*edges;
        edges=new DGGSElementCode[1];
        edges[0]=code;
        edges[0].elementType=DGGSElementType::Edge;

        edges[0].levelZ=-1;
        int cellNum=0;
        DGGSElementCode *cells= nullptr;
        this->fromEdgeGetAssociationBoundary(edges[0],cells,cellNum);

        for(int i=0;i<cellNum;i++)
        {
            results[i]=cells[i];
            results[i].elementType=DGGSElementType::Voxel;
            results[i].levelZ=code.levelZ;
        }
        delete [] edges;
        edges= nullptr;
        delete[]cells;
        cells= nullptr;
    }
}

//边找体
void ISEA4TQuery::fromEdgeGetRelativeVoxels(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    if(code.elementType==DGGSElementType::SideEdge)
    {
        DGGSElementCode *vertex;
        vertex=new DGGSElementCode[1];
        vertex[0]=code;
        vertex[0].elementType=DGGSElementType::Vertex;
        vertex[0].levelZ=-1;

        DGGSElementCode * cells;
        int cellNum=0;
        this->fromVertexSearchRelativeCells(vertex[0],cells,cellNum);
        elementNum=cellNum;
        results=new DGGSElementCode[elementNum];

        for(int i=0;i<elementNum;i++)
        {
            results[i]=cells[i];
            results[i].elementType=DGGSElementType::Voxel;
            results[i].levelZ=code.levelZ;
        }
        delete[]cells;
        cells= nullptr;
        delete[]vertex;
        vertex= nullptr;
    }
    else if(code.elementType==DGGSElementType::Edge)
    {
        elementNum=4;
        results=new DGGSElementCode[elementNum];

        int levelD=code.levelZ;
        code.levelZ=-1;
        DGGSElementCode * cells;
        int cellNum=0;
        this->fromEdgeGetAssociationBoundary(code,cells,cellNum);
        for(int i=0;i<cellNum;i++)
        {
            results[i]=cells[i];
            results[i].elementType=DGGSElementType::Voxel;
            results[i].levelZ=levelD;

            results[i+cellNum]=results[i];
            results[i+cellNum].levelZ= levelD + 1;
        }
        delete[]cells;
        cells= nullptr;
    }
}

//点找体
void ISEA4TQuery::fromVertexGetRelativeVoxels(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    int levelD=code.levelZ;
    code.levelZ=-1;
    DGGSElementCode * cells;
    int cellNum=0;
    this->fromVertexSearchRelativeCells(code,cells,cellNum);
    elementNum=cellNum*2;
    results=new DGGSElementCode[elementNum];

    for(int i=0;i<cellNum;i++)
    {
        results[i]=cells[i];
        results[i].elementType=DGGSElementType::Voxel;
        results[i].levelZ=levelD;

        results[i+cellNum]=results[i];
        results[i+cellNum].levelZ= levelD + 1;
    }
    delete[]cells;
    cells= nullptr;
}

//体找体
void ISEA4TQuery::fromVoxelGetRelativeVoxels(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    DGGSElementCode cell=code;
    cell.elementType=DGGSElementType::Cell;
    cell.levelZ=-1;

    DGGSElementCode *cells;
    int cellNum;
    this->fromCellGetRelativeCells(cell,cells,cellNum);
    elementNum=cellNum+2;
    results=new DGGSElementCode[elementNum];
    for(int i=0;i<cellNum;i++)
    {
        results[i]=cells[i];
        results[i].elementType=DGGSElementType::Voxel;
        results[i].levelZ=code.levelZ;
    }

    results[elementNum-2]=code;
    results[elementNum-2].elementType=DGGSElementType::Voxel;
    results[elementNum-2].levelZ= code.levelZ - 1;

    results[elementNum-1]=code;
    results[elementNum-1].elementType=DGGSElementType::Voxel;
    results[elementNum-1].levelZ= code.levelZ + 1;

    delete[]cells;
    cells= nullptr;
}

